package eu.smoothit.sis.admin.backendBean;

import java.io.IOException;
import org.jboss.security.auth.spi.Util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpSession;

import eu.smoothit.sis.admin.backendBean.superclass.DataTableAbstract;
import eu.smoothit.sis.db.SisDAOFactory;
import eu.smoothit.sis.db.api.daos.IUserDAO;
import eu.smoothit.sis.db.api.daos.IUserRoleDAO;
import eu.smoothit.sis.db.impl.entities.User;
import eu.smoothit.sis.db.impl.entities.UserRole;

public class SecurityAdminUserBean extends DataTableAbstract<User> {
	// Properties
	// ---------------------------------------------------------------------------------
	private User searchExample;
	private List<SelectItem> allRoles;
	private List<String> associatedRoleGroupRoleNames;
	private boolean usersAssociatedRoleGroupEditable;
	// define DAO
	private IUserRoleDAO roleDAO = (IUserRoleDAO) SisDAOFactory.getFactory()
			.createUserRoleDAO();
	private IUserDAO userDAO = (IUserDAO) SisDAOFactory.getFactory()
			.createUserDAO();

	// initialization
	public SecurityAdminUserBean() {
		searchExample = new User();
		setUsersAssociatedRoleGroupEditable(false);
		actionLoad();
	}

	// getter && setter
	// ----------------------------------------------------------------------------------
	public List<SelectItem> getAllRoles() {
		return allRoles;
	}

	public void setAllRoles(List<SelectItem> allRoless) {
		this.allRoles = allRoless;
	}

	public boolean getUsersAssociatedRoleGroupEditable() {
		return usersAssociatedRoleGroupEditable;
	}

	public void setUsersAssociatedRoleGroupEditable(
			boolean usersAssociatedRoleGroupEditable) {
		this.usersAssociatedRoleGroupEditable = usersAssociatedRoleGroupEditable;
	}

	public List<String> getAssociatedRoleGroupRoleNames() {
		return associatedRoleGroupRoleNames;
	}

	public void setAssociatedRoleGroupRoleNames(
			List<String> associatedRoleGroupRoleNames) {
		this.associatedRoleGroupRoleNames = associatedRoleGroupRoleNames;
	}

	public User getSearchExample() {
		return searchExample;
	}

	public void setSearchExample(User searchExample) {
		this.searchExample = searchExample;
	}

	// Form actions
	// ----------------------------------------------------------------------------------
	public List<SelectItem> fetchAllRoles() {
		List<UserRole> roles;
		List<SelectItem> roleAsSelectItems = new ArrayList<SelectItem>();
		roles = roleDAO.getAll();
		for (UserRole u : roles) {
			roleAsSelectItems.add(new SelectItem(u.getRole() + "|"
					+ u.getRoleGroup()));
		}
		return roleAsSelectItems;

	}

	@Override
	public void actionSave() {
		List<User> editItems = new ArrayList<User>();
		for (int index = 0; index < dataList.size(); index++) {
			if (isEditModeRow(index)) {
				editItems.add(dataList.get(index));
			}
		}
		Collection<User> foundUserList = new ArrayList<User>();
		User existedUser = new User();
		for (User editItem : editItems) {
			String hash = Util.createPasswordHash("MD5",Util.BASE64_ENCODING, null, null,editItem.getPassword());
			editItem.setPassword(hash);
			if (editItem.getId() == null) {
				existedUser.setUsername(editItem.getUsername());
				foundUserList = userDAO.get(existedUser);
				if (foundUserList.isEmpty()) {
					try {
						// id=null stand for new added entry
						userDAO.persist(editItem);
					} catch (Exception e) {
						setErrorMessage(e.getMessage() + " Cause: "
								+ e.getCause());
						e.printStackTrace();
						return;
					}
					// Toggle edit mode and reload data.
					editMode = false;
					actionLoad();
				} else {
					String message = "Input user name "
							+ editItem.getUsername()
							+ " exists in database, duplicated is not allowed";
					setErrorMessage(message);
					return;
				}
			} else {
				try {
					// otherwise, it is existing entry, update it.
					userDAO.update(editItem);
				} catch (Exception e) {
					setErrorMessage(e.getMessage() + " Cause: " + e.getCause());
					e.printStackTrace();
					return;
				}
				// Toggle edit mode and reload data.
				editMode = false;
				actionLoad();
			}
		}

	}

	@Override
	public void actionDelete() {
		// Get selected items.
		List<User> deleteItems = new ArrayList<User>();

		for (int index = 0; index < dataList.size(); index++) {
			if (isSelectedRow(index)) {
				deleteItems.add(dataList.get(index));
			}
		}
		if (deleteItems.isEmpty()) {
			setErrorMessage("Select at least one item to delete.");
			return;
		}
		Collection<UserRole> roles;
		for (User deleteItem : deleteItems) {
			// Check if there are roles assoicated with the user, before delete action.
			roles = deleteItem.getUserRoles();
			if (roles.isEmpty()) {
				try {
					userDAO.remove(deleteItem);
				} catch (Exception e) {
					setErrorMessage(e.getMessage() + " Cause: " + e.getCause());
					e.printStackTrace();
					return;
				}
			} else {
				String message = "Disassociate from role before delete!";
				setErrorMessage(message);
				return;
			}

		}
		// Reload data and go to first page.
		actionLoad();
		pageFirst();
	}

	@Override
	public void actionLoad() {
		try {
			dataList = userDAO.getAll(); // list();
		} catch (Exception e) { // TODO add this to <h:messages>
			setErrorMessage(e.getMessage() + " Cause: " + e.getCause());
			e.printStackTrace();
			return;
		}
		// Clear selected and editmode rows and sort data.
		setAllRoles(fetchAllRoles());
		actionSort(null);
	}

	public void actionAdd() {
		actionAdd(new User());
	}

	public void actionRefresh() {
		searchExample = new User();
		setUsersAssociatedRoleGroupEditable(false);
		super.actionRefresh();
	}

	public String togglePage() {
		actionLoad();
		return "securityAdminUser";
	}

	public String logout() throws IOException

	{
		ExternalContext ectx = FacesContext.getCurrentInstance()
				.getExternalContext();
		HttpSession session = (HttpSession) ectx.getSession(false);
		// HttpServletResponse response = (HttpServletResponse)
		// ectx.getResponse();
		if (session != null) {
			System.out.println("pass sesssion is null");
			session.invalidate();
		}
		// response.sendRedirect("/index.html");
		return "logout";

	}

	// Listeners
	// ---------------------------------------------------------------
	public void fetchAssociatedRoleGroups(ActionEvent e) {
		User selectedUser = (User) dataTable.getRowData();
		Collection<UserRole> userRoles = selectedUser.getUserRoles();
		List<String> roleNames = new ArrayList<String>();
		for (UserRole r : userRoles) {
			roleNames.add(r.getRole() + "|" + r.getRoleGroup());
		}
		setAssociatedRoleGroupRoleNames(roleNames);
		setUsersAssociatedRoleGroupEditable(true);
		editModeRows.put(dataTable.getRowIndex(), true);
	}

	public void saveAssociatedUsers(ActionEvent e) {
		User selectedUser = (User) dataTable.getRowData();
		selectedUser = userDAO.get(selectedUser).get(0);
		UserRole entity;
		Collection<UserRole> matchedRoles = new ArrayList<UserRole>();
		for (String roleGroup : getAssociatedRoleGroupRoleNames()) {
			entity = new UserRole();
			String roleName = roleGroup.split("\\|")[0];
			String groupName = roleGroup.split("\\|")[1];
			entity.setRole(roleName);
			entity.setRoleGroup(groupName);
			matchedRoles.add(roleDAO.get(entity).get(0));
		}
		selectedUser.setUserRoles(matchedRoles);
		userDAO.update(selectedUser);
		actionRefresh();
	}
	
//	@Override
//	public void actionEdit(){
//		super.actionEdit();
//		
//	}
	

}